/**
 * FileName: LoginController
 * Author: TangZaoBang
 * Date: 2023/06/05 13:09
 * Description: 登录控制器
 * <p>
 * History:
 * <author> TangZaoBang
 * <time> 2023/06/05 13:09
 * <version> 1.0.0
 * <desc> 版本描述
 */
package com.sd365.permission.centre.api.controller;
import cn.hutool.http.HttpStatus;
import com.sd365.common.core.common.exception.BusinessException;
import com.sd365.common.core.context.BaseContextHolder;
import com.sd365.common.util.BeanUtil;
import com.sd365.common.util.StringUtil;
import com.sd365.permission.centre.api.LoginApi;
import com.sd365.permission.centre.entity.Role;
import com.sd365.permission.centre.entity.User;
import com.sd365.permission.centre.pojo.dto.CompanyDTO;
import com.sd365.permission.centre.pojo.dto.RoleDTO;
import com.sd365.permission.centre.pojo.dto.UserDTO;
import com.sd365.permission.centre.pojo.vo.ResourceVO;
import com.sd365.permission.centre.service.CompanyService;
import com.sd365.permission.centre.service.LoginService;
import com.sd365.permission.centre.service.UserOnlineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;


/**
 * 主要通过转发控制登录
 * @author TangZaoBang
 * @date 2023/06/11 01:53
 * @version: v1.0.0
 */
@RestController
@Slf4j
@Validated
public class LoginController implements LoginApi {

    /**
     * 登录服务
     */
    @Autowired
    private LoginService loginService;
    /**
     * 公司服务
     */
    @Autowired
    private CompanyService companyService;
    /**
     * 用户在线服务
     */
    @Autowired
    private UserOnlineService userOnlineService;

    /**
     * 用于进行用户认证并返回带权限的UserVO对象
     * @author TangZaoBang
     * @date 2023/06/11 17:07
     * @param code 账号
     * @param password 密码
     * @param account 租户号
     * @return com.sd365.permission.centre.api.LoginApi.UserVO
     */
    @Override
    public UserVO auth(@RequestParam(value = "code") @NotNull String code,
                       @RequestParam(value = "password") @NotNull String password,
                       @RequestParam(value = "account") @NotNull String account) {
        UserVO userVO = new UserVO();
       UserDTO userDTO = loginService.auth(code, password, account);
        setAuthSuccessData(userVO, userDTO);
        return userVO;
    }


    /**
    * 验证账号密码和account 并登录
    * @author TangZaoBang
    * @date 2023/06/05 17:02
    * @param code 账号
    * @param password 密码
    * @param account 租户号
    * @return com.sd365.permission.centre.api.LoginApi.UserVO
    */
    @Override
    public UserVO login(@NotNull @RequestParam(value = "code") String code,
                        @NotNull @RequestParam(value = "password") String password,
                        @NotNull @RequestParam(value = "account") String account) {
        // 根据user.code, user.password, tenant.account
        UserVO userVO = BeanUtil.copy(loginService.login(code,password,account), UserVO.class);
        userVO.data = new ResponseData();
            userVO.data.setToken("1");
            userVO.setCode(200);
            userVO.setMsg("登录成功");
        return userVO;
    }

    /**
     * 前端认证完成后调用此方法获取用户信息，用户信息包含权限信息
     * @author TangZaoBang
     * @date 2023/06/07 14:57
     * @param code code 工号
     * @param account account 租户账号
     * @return com.sd365.permission.centre.api.LoginApi.UserVO
     */
    @Override
    public UserVO info(@NotNull @RequestParam(value = "code") String code, @NotNull @RequestParam(value = "account") String account) {
        User user = loginService.getUserInfo(code, account);
        if (user==null){
          return new UserVO();
        }
        List<Role> roles = loginService.getRolesByUserId(user.getId());
        List<String> rolesName = getRoleNames(roles);
        UserVO userVO = createUserVO(user, rolesName);
        setResourceVO(userVO, roles);
        setUserAdditionalInfo(userVO, code, account);
        return userVO;
    }

    @Override
    public UserVO logout() {
        String logoutId = BaseContextHolder.getUserIdStr();
        userOnlineService.forceLogout(logoutId);
        UserVO userVO = new UserVO();
        userVO.data = new ResponseData();
        userVO.setCode(HttpStatus.HTTP_OK);
        return userVO;
    }


    /**
     * 设置认证成功时的UserVO对象数据
     * @author TangZaoBang
     * @date 2023/06/11 17:10
     * @param userVO 要传出的VO
     * @param loginUserDTO service查到的DTO
     * @return void
     */
    private void setAuthSuccessData(@NotNull UserVO userVO,@NotNull UserDTO loginUserDTO) {
        ResponseData responseData = new ResponseData();
        responseData.setToken("");
        responseData.setName(loginUserDTO.getName());
        userVO.setId(loginUserDTO.getId());
        userVO.setData(responseData);
        List<Long> idList = new ArrayList<>();
        List<RoleDTO> roleDTOArrayList= loginUserDTO.getRoleList();
        for (RoleDTO roleDTO:roleDTOArrayList){
            idList.add(roleDTO.getId());
        }
        userVO.setRoleIds(idList);
        userVO.setTenantId(loginUserDTO.getTenantId());
        userVO.setOrgId(loginUserDTO.getOrgId());
        userVO.setCompanyId(loginUserDTO.getCompanyId());
        userVO.setCode(HttpStatus.HTTP_OK);
        userVO.setMsg("登录成功");
    }


    /**
     * 获取角色名称列表
     * @author TangZaoBang
     * @date 2023/06/11 17:13
     * @param roles
     * @return java.util.List<java.lang.String>
     */
    private List<String> getRoleNames(List<Role> roles) {
        List<String> rolesName = new LinkedList<>();
        for (Role role : roles) {
            rolesName.add(role.getName());
        }
        return rolesName;
    }


    /**
     * 创建UserVO对象
     * @author TangZaoBang
     * @date 2023/06/11 17:13
     * @param user
     * @param rolesName
     * @return com.sd365.permission.centre.api.LoginApi.UserVO
     */
    private UserVO createUserVO(User user, List<String> rolesName) {
        UserVO userVO = new UserVO();
        userVO.data = new ResponseData();
        userVO.data.setAvatar(user.getProfilePicture());
        userVO.data.setRoles(rolesName);
        userVO.data.setName(user.getName());
        userVO.setCode(HttpStatus.HTTP_OK);
        userVO.setTel(user.getTel());
        userVO.setTenantId(user.getTenantId());
        userVO.setCompanyId(user.getCompanyId());
        userVO.setOrgId(user.getOrgId());
        userVO.setId(user.getId());
        userVO.setMsg("登录成功");
        return userVO;
    }

    /**
     * 设置ResourceVO对象
     * @author TangZaoBang
     * @date 2023/06/11 17:13
     * @param userVO
     * @param roles
     * @return void
     */
    private void setResourceVO(UserVO userVO, List<Role> roles) {
        if (!roles.isEmpty()) {
            List<ResourceVO> resourceVOs = loginService.getResourceVO(roles);
            userVO.data.setResourceVO(resourceVOs);
            log.debug("##resourceVOS:" + resourceVOs);
        }
    }

    /**
     *设置用户额外信息
     * @author TangZaoBang
     * @date 2023/06/11 17:13
     * @param userVO 传入的Vo
     * @param code 工号
     * @param account 租户账号
     * @return void
     */
    private void setUserAdditionalInfo(UserVO userVO, String code, String account) {
        User userInfo = loginService.getUserInfo(code, account);
        userVO.setId(userInfo.getId());
        CompanyDTO companyDTO = companyService.queryById(userInfo.getCompanyId());
        userVO.setCompanyAddress(StringUtil.isEmpty(companyDTO.getAddress()) ? companyDTO.getAddress() : "您的默认单位地址");
    }




}
